package com.leetcode;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * <p>
 * Scanner使用示例：https://blog.csdn.net/u013568373/article/details/92803182
 * </p>
 * <p>
 * Scanner类需要实例化：
 * Scanner s = new Scanner(System.in) ：从键盘接收数据
 * Scanner s = new Scanner(new File) ：从文件接收数据
 * <p>
 * 一：nextInt
 * 在有效字符前遇到空白，方法会自动去掉空白；
 * 读取到有效字符后遇到空白，空白会被当成结束符或者分隔符；
 * 必须要读取到有效的输入
 * <p>
 * 二：nextLine
 * 以Enter为结束符, 也就是说 nextLine()方法返回的是输入回车之前的所有字符。
 * 可以获得空白
 * <p>
 * 三：hasNextDouble
 * 输入多个数字，每输入一个数字用回车确认，通过输入非数字来结束输入并输出执行结果
 *
 * @author: Sunny
 * @date: 2021/3/9
 * @version: v1.0.0
 */
public class ScannerTest {

    /**
     * 1：Scanner#next：从遇到的第一个有效字符（非空格、非换行）开始扫描，直到遇到空格或者换行符。
     * <p>
     * 2：Scanner#nextLine：从遇到的第一个有效字符（非空格、非换行）开始扫描，直到遇到换行符。
     * ```
     * next和nextLine的区别：
     * next："空格或者换行符"作为分隔点。
     * nextLine："换行符"作为分隔点。
     * ```
     * <p>
     * 3：Scanner#nextInt：跟next()很像，都是以空格或者换行符作为扫描终点。
     * <p>
     * 4：Scanner#hasNext：断输入流里是否还有内容，有就返回true。
     * <p>
     * 注意点：
     * 换行符（键盘上的Enter键）：Scanner的结束符，然后代码会处理你的输入。
     * 空格（键盘上的Space键） + 换行符（键盘上的Enter键）：Scanner的分隔符。
     * 除了nextLine()，其它nextXXX()默认采用空格进行分割！记住是空格分割！nextLine()应该是判断一行的末尾来进行分割
     *
     * @param args
     */
    public static void main(String[] args) {
        // next
        //nextTest();

        // nextLine
        //nextLineTest();

        // nextInt
        //nextIntTest();

        // hasNext
        //hasNextTest();

        // hasNextInt / hasNextFloat
        //intOrFloatTest();

        // hasNextDouble
        //hasNextDoubleTest();

        // Scanner实现多行输入
        //multipleLine();

        multipleLineInput();
    }

    /**
     * 参考：https://www.nowcoder.com/practice/de044e89123f4a7482bd2b214a685201?tpId=37&tqId=21231&rp=1&ru=%2Fta%2Fhuawei%2F&qru=%2Fta%2Fhuawei%2Fquestion-ranking&tab=answerKey
     * 多行输入问题示例
     */
    public static void multipleLineInput() {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            Map<Integer, Integer> map = new HashMap<>();
            // 输入键值对的个数
            int n = scanner.nextInt();
//            System.out.println("n的数字为：" + n);
            for (int i = 0; i < n; i++) {
                int index = scanner.nextInt();
                int value = scanner.nextInt();
                if (map.containsKey(index)) {
                    map.put(index, map.get(index) + value);
                } else {
                    map.put(index, value);
                }
            }
            for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " " + entry.getValue());
            }
        }

    }

    /**
     * Scanner实现多行输入
     */
    public static void multipleLine() {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            System.out.println(a + " = " + b);
        }

    }

    /**
     * hasNext()方法用作while()的条件判断时，会导致程序不能跳出循环，参考{ScannerTest#nextTest}。
     * hasNextDouble()方法用作while()的条件判断时，只要输入不是double类型，则会退出循环，参考{ScannerTest#hasNextDoubleTest}。z
     */
    public static void hasNextDoubleTest() {
        Scanner scanner = new Scanner(System.in);
        double sum = 0;
        int m = 0;

        System.out.println("请输入需要计算的数字 : ");

        // 结束时输入任意字母，则就不会满足while条件，则会结束循环
        while (scanner.hasNextDouble()) {
            double x = scanner.nextDouble();
            m = m + 1;
            sum = sum + x;
        }
        System.out.println("输入的和为 : " + sum);
        System.out.println("输入的平均值为 : " + (sum / m));
    }

    /**
     * 如果输入int和float类型数据，在输入之前可以先判断验证后使用
     */
    public static void intOrFloatTest() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入整数：");
        if (scanner.hasNextInt()) {
            int i = scanner.nextInt();
            System.out.println("i = " + i);
        } else {
            System.out.println("输入的不是整数");
        }

        if (scanner.hasNextFloat()) {
            float i = scanner.nextFloat();
            System.out.println("i = " + i);
        } else {
            System.out.println("输入的不是小数");
        }
    }

    /**
     * 请输入：hasNext() will block your code!
     * 扫描到第1段匹配的内容：hasNext()
     * 扫描到第2段匹配的内容：will
     * 扫描到第3段匹配的内容：block
     * 扫描到第4段匹配的内容：your
     * 扫描到第5段匹配的内容：code!
     */
    public static void hasNextTest() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入：");
        int matchNum = 1;
        while (scanner.hasNext()) {
            System.out.print("扫描到第" + matchNum + "段匹配的内容：");
            System.out.println(scanner.next());
            matchNum++;
        }
        // 如果你在实例化 Scanner 的时候构造函数使用的是System.in作为输入流传入，那么就算读完了hasNext()也会一直阻塞你的代码。
        // 本地debug的时候可以将数据写到File中，使用Scanner(File source)构造方法。
        System.out.println("能到这儿吗？");
    }

    /**
     * nextInt：以"空格或换行符"作为分隔点
     * 请输入：1 2 3 4
     * 扫描到第1段匹配内容：1
     * 扫描到第2段匹配内容：2
     * 扫描到第3段匹配内容：3
     * 扫描到第4段匹配内容：4
     */
    public static void nextIntTest() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入：");
        int matchNum = 1;
        while (scanner.hasNext()) {
            System.out.print("扫描到第" + matchNum + "段匹配内容：");
            System.out.println(scanner.nextInt());
            matchNum++;
        }
    }

    /**
     * next：以"换行符"作为分隔点
     * 输入：A B C D
     * 输出：
     * 扫描到第1段匹配内容：A B C D
     */
    public static void nextLineTest() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入：");
        int matchNum = 1;
        while (scanner.hasNext()) {
            System.out.print("扫描到第" + matchNum + "段匹配内容：");
            System.out.println(scanner.nextLine());
            matchNum++;
        }
    }


    /**
     * next：以"空格或换行符"作为分隔点
     * 输入：A B C D
     * 输出：
     * 扫描到第1段匹配内容：A
     * 扫描到第2段匹配内容：B
     * 扫描到第3段匹配内容：C
     * 扫描到第4段匹配内容：D
     * <p>
     * 注：hasNext()用作while()的条件判断时，会导致程序不能跳出循环。
     */
    public static void nextTest() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入：");
        int matchNum = 1;
        while (scanner.hasNext()) {
            System.out.print("扫描到第" + matchNum + "段匹配内容：");
            System.out.println(scanner.next());
            matchNum++;
        }
    }

}
